#pragma once
#include "Socket.hpp"
#include "Service.hpp"
#include <signal.h>
#include <functional>
#include "Log.hpp"
using std:: cout;
using std:: cin;
using std:: endl;

using func_t = std::function<std::string(std::string& package)>;

class TcpServer
{
private:
    uint16_t _port;
    Socket _listensock;
    func_t _ServiceCal;

public:
    TcpServer(uint16_t port, func_t func)
        :_port(port)
        ,_ServiceCal(func)
    {}
    
    ~TcpServer(){}

public:
    //1.建立起连接 + 准备为客户端提供服务
    void Init();
    void Start();

};


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TcpServer::Init()
{
    _listensock.Create();
    _listensock.Bind(_port);
    _listensock.Listen();
    lg(Info, "Tcp Init success");
}

void TcpServer::Start()
{
    signal(SIGCLD,SIG_IGN);

    while(1)
    {
        std::string client_ip;
        uint16_t client_port;
        int newsocket = _listensock.Accept(&client_ip, &client_port);
        if(newsocket < 0)continue;

        //提供服务--多进程
        if(fork() == 0)
        {
            _listensock.Close();

            //处理数据
            std::string req_package;
            while(1)
            {
                char buffer[128];
                ssize_t n = read(newsocket, buffer, sizeof(buffer));
                if(n > 0)
                {
                    
                    buffer[n] = 0;
                    lg(Info, "get a request");
                    cout << buffer << endl;
                    req_package += buffer;
                    std::string back = _ServiceCal(req_package);//调用函数处理数据
                    if(back.empty())continue;

                    write(newsocket, back.c_str(), back.size());
                }           
                else break;        
            }

            exit(0);
        }
        close(newsocket);

    }

}



